About Group Objects
A group object (or, more briefly, a group) is a type of QuickDraw 3D object that you can use to collect objects together into lists or hierarchical models. A group object is an instance of theTQ3GroupObject
class. As you've seen, theTQ3GroupObject
class is a subclass of theTQ3ShapeObject
, which is itself a subclass of theTQ3SharedObject
class. As a result, a group object is associated with a reference count, which is incremented or decremented whenever you create or dispose of an instance of that group.The objects you put into in a group are not copied into the group. Instead, references to the objects are maintained in the group. Accordingly, you can include in a group only shared objects (that is, the types of objects that have reference counts). A group can contain other groups, because groups are shared objects. QuickDraw 3D provides functions that you can use to add objects to a group or remove objects from a group. It also provides functions that you can use to access objects by their position in the group.
Group Types
The base class of group object is of typekQ3ShapeTypeGroup
, a type of shape object. You can create a group of that type (by calling theQ3Group_New
function) and you can put any kinds of shared objects into it (for example, by calling theQ3Group_AddObject
function). In addition, QuickDraw 3D provides three subclasses of groups: light groups, display groups, and information groups. These subclasses are distinguished from one another by the kinds of objects you can put into them.
- A light group is a group that contains one or more lights (and no other types of QuickDraw 3D objects). You'll typically create light groups to provide illumination on the objects in a model. The light group is attached to a view object by calling the
Q3View_SetLightGroup
function. See the chapter "View Objects" for complete details on attaching light groups to views.- A display group is a group of objects that are drawable. Drawable objects include geometric objects, styles, transforms, attributes and attribute sets, and other display groups. When you draw a display group into a view, each object in the group is executed (that is, drawn) in the order in which it appears in the group (which is determined by the order in which the objects were inserted into the group). You can create a display group, or you can create one of two subclasses of display groups: ordered display groups and I/O proxy display groups.
This order of execution ensures that all transforms, styles, attribute
- transforms
- styles
- attribute sets
- shaders
- geometric objects
- groups
- unknown objects
sets, and shaders in a group are applied to the geometric objects,
groups, and unknown objects that form the hierarchy below the
ordered display group.
- An I/O proxy display group (or sometimes proxy display group) is a display group that contains several representations of a single geometric object. You can use I/O proxy display groups to encapsulate, in a metafile, two or more descriptions of an object. This is useful when
an application reading the file is unable to understand some of those descriptions. For example, you might know that some other applications cannot handle NURB patches but do handle meshes. As a result, you can create an I/O proxy display group that contains two descriptions of a surface (one as a NURB patch and one as a mesh) and write that group into a metafile. Any application reading the metafile can select from the display group the representation of the surface that it can work with. You should put objects into the I/O proxy display group in the order you deem to be preferable. (In other words, the first object in the group should be the representation you deem most useful, and the last object should be the one that you deem least useful.) In this way, an application reading the metafile can simply use the first object in the proxy display group whose type is notkQ3SharedTypeUnknown
.
- An information group is a group that contains one or more strings (and no other types of QuickDraw 3D objects). You'll typically create information groups to provide human-readable information in a metafile. For example, if you want to include a copyright notice in a metafile, you can simply create an information group that contains a string of the appropriate data and then write that group to the metafile.
Group Positions
You access an object within a group (for example, to remove the object from the group or to replace it with some other object) by referring to the object's group position. A group position is a pointer to a private (that is, opaque) data structure maintained internally by QuickDraw 3D. A group position is defined by theTQ3GroupPosition
data type.
typedef struct TQ3GroupPositionPrivate *TQ3GroupPosition;You receive a group position for an object when you first insert the object into the group (for example, by callingQ3Group_AddObject
). In general, however, you don't need to maintain that information, because you can use QuickDraw 3D routines to walk through a group. For instance, you can get
the group position of the first object in a group by callingQ3Group_GetFirstPosition
. Then you can retrieve the positions of all subsequent objects in the group by callingQ3Group_GetNextPosition
.
See "Accessing Objects by Position," beginning on page 10-8 for sample code that illustrates how to traverse a group using group positions.
- IMPORTANT
- An object's group position is valid only as long as that object is in the group. When you remove an object from a group, the corresponding group position becomes invalid. Similarly, when you remove all objects from a group (for example, by calling
Q3Group_EmptyObjects
), the group positions of those objects become invalid.![]()
Group State Flags
Every display group has group state value (built out of a set of group state flags) that determine how the group is traversed during rendering or picking, or during the computation of a bounding box or sphere. Here are the currently defined group state flags:
typedef enum TQ3DisplayGroupStateMasks { kQ3DisplayGroupStateNone = 0, kQ3DisplayGroupStateMaskIsDrawn = 1 << 0, kQ3DisplayGroupStateMaskIsInline = 1 << 1, kQ3DisplayGroupStateMaskUseBoundingBox = 1 << 2, kQ3DisplayGroupStateMaskUseBoundingSphere = 1 << 3, kQ3DisplayGroupStateMaskIsPicked = 1 << 4, kQ3DisplayGroupStateMaskIsWritten = 1 << 5 } TQ3DisplayGroupStateMasks;A group state value contains a flag, called the drawable flag, that determines whether the group is to be drawn when it is passed to a view for rendering or picking. By default, the drawable flag of a group state value is set, indicating that the group is to be drawn to a view. If the drawable flag is clear, the group is not traversed when it is encountered in a hierarchical model. This allows you to place "invisible" objects in a model that assist you in bounding complex geometric objects, for example.An ordered display group can be constructed in such a way that the group has a hierarchical structure. This allows properties (such as attributes, styles, and transforms) to be inherited by child nodes from their parent nodes in the hierarchy. Occasionally, however, you might want to override this inheritance and allow a group contained in a hierarchical model to define its own graphics state independently of any other objects or groups in the model. To allow this feature, a group state value contains an inline flag that specifies whether or not the group should be executed inline. A group is executed inline if it does not push and pop the graphics state stack before and after it is executed (that is, if it is simply executed as a bundle of objects). By default, the inline flag of a group is not set, indicating that the group pushes and pops its graphics state.
A group state value contains a picking flag that determines whether the group can be picked. In general, you'll want all groups in a model to be eligible for picking. In some cases, however, you can clear the picking flag of a group's group state value in order to establish the group as a decoration in the model that cannot be picked.
- Note
- For more information on pushing and popping the graphics state, see the descriptions of the functions
Q3Push_Submit
andQ3Pop_Submit
in the chapter "View Objects."![]()